#include "mutex.h"

void lock(int *m){
	asm ("loop: addu $8, $0, 1;"
		 ".set mips2\n" 
		 "ll $9, ($4);"
		 ".set mips1\n" 
		 "bne $9, $0, loop;"
		 "nop;"
		 ".set mips2\n" 
		 "sc $8, ($4);"
		 ".set mips1\n" 
		 "beq $8, $0, loop;"
		 "nop;"
		 :			
		 :"r" (m)         
		 );  		
}

void unlock(int *m){
	asm ("sw $0, ($4)"
		 :				
		 :"r" (m)       
		 );  		
}

// from: http://www.memoryhole.net/kyle/2007/05/atomic_incrementing.html
void atomic_incr(int * operand, int incr)
{
	asm ("loop1: \n"
		 ".set mips2\n" 
		 "ll $8, ($4);"
		 ".set mips1\n" 
		 "addu $8, $8, $5;"
		 ".set mips2\n" 
		 "sc $8, ($4);"
		 ".set mips1\n" 
		 "beq $8, $0, loop1;"
		 "nop;"
		 :: "r" (operand), "r" (incr)
		 ); 
}
